root_path <- "~/Desktop/raw_data_must/"
chrom_path <- paste0(root_path, "Chromium/")
vis_path <- paste0(root_path, "Visium/outs/")
xe_path <- paste0(root_path, "Xenium/outs/")
aggxe_path <- paste0(root_path, "AggXe/outs/")
suppressMessages({
library(Seurat)
library(BayesSpace)
library(ggplot2)
library(patchwork)
library(dplyr)
library(tibble)
library(scater)
library(scran)
library(scuttle)
library(grid)
library(hrbrthemes)
library(gridExtra)
library(SingleR)
library(magick)
library(harmony)
library(scales)
library(knitr)
library(here)
library(cowplot)
})
source("utils_new.R")
First, we check the similarity between Visium and Xenium images. Visium comes with a H&E image.
Then we visualize the Xenium image. It can be obtained by taking a screenshot of the .ome.tif object in Xenium raw data, which was read in using a Java software Fiji. Note that after some scaling and rotation, Xenium can be aligned to Visium. In image processing, such transformation can be done by multiplying the source image with a linear affine transformation matrix, to map it onto the same scale as the target image.
ggdraw() +
draw_image("www/tissue_lowres_image.png", width = 0.55) +
draw_label ("Visium H&E", hjust = 0, vjust = 0, x = 0, y = 0.95) +
draw_image("www/img_xe_rotate_scale.png", width = 0.25, x = 0.7) +
draw_label ("Xenium .ome.tif (rotate & shrink)", hjust = 0, vjust = 0, x = 0.6, y = 0.95)
There are many ways of image registration in R, Python, with other plug-ins.
SpatialData is a Python package that requires
user-selected landmarks to align images. Here shows the registration of
Visium onto Xenium in SpatialData’s napari interface.
RNiftyReg can be combined with
mmand for automated image registration. After alignment, we
will obtain the registered images with a transformation matrix. Here is
a demonstration with external data, before and after registration of two
slices.
Therefore, we use the transformation matrix provided by 10x, which was done by registration with Python and a Java plug-in Fiji. The following matrix is the result of registering Xenium onto Visium.
# Affine matrix aligned by 10X
trans_mtx <- matrix(
c(
8.82797498e-02, -1.91831377e+00, 1.63476055e+04,
1.84141210e+00, 5.96797885e-02, 4.12499099e+03,
-3.95225478e-07, -4.66405945e-06, 1.03706895e+00
),
nrow = 3, byrow= TRUE
)
trans_mtxWe have developed a Bioconductor R package for binning any
single-cell resolution spatial data into spots, which can be useful in
checking correlations between technical replicates of the same
technology, identify artifacts across technologies, and checking cell
density (number of cells per spot). The user can choose to bin from
transcript-level (sub-cellular) or cell-level. Our package
bin2spot will soon be available to the public after some
optimization with the speed in the backend.
# aggxe <- bin2spot::aggregate_xenium(xe, scaling_factor)
For this tutorial, we have saved the output of the binned Xenium object, aggregated by our lab member.
Here is the result of post affine transformation and aggregation, the
aligment of Xenium onto Visium.